from pathlib import Path
from typing import Optional, List

from openpyxl import load_workbook
from pydantic import BaseModel

from .export_as_excel import Exporter
from .import_from_excel import (
    import_products_from_tender,
    import_products_from_bid,
    unmerge_and_fill_cells,
)
from .process import add_supplier
from .schema import SummaryTable

AVAILABLE_SHEET_NAMES = ["PPR管阀", "PVC PP 及RPP管件", "CPVC管"]


class Bidder(BaseModel):
    name: str
    document: Path
    has_bargaining: bool = False
    bargaining_document: Optional[Path] = None


class Consolidator:
    def __init__(self, tender_document: Path, summary_document: Path):
        self.tender_document = tender_document
        self.summary_document = summary_document
        self.summary_tables: List[SummaryTable] = []

    def load_tender(self):
        tender_workbook = load_workbook(self.tender_document)
        sheet_names = tender_workbook.sheetnames
        valid_sheet_names = [
            name for name in sheet_names if name in AVAILABLE_SHEET_NAMES
        ]
        for sheet_name in valid_sheet_names:
            sheet = tender_workbook[sheet_name]
            unmerge_and_fill_cells(sheet)
            summary_table = import_products_from_tender(sheet)
            self.summary_tables.append(summary_table)
        tender_workbook.close()

    def add_bids(self, bid_documents: List[Bidder]):
        for bid_document in bid_documents:
            print(f"Processing bid from supplier: {bid_document.name}")
            try:
                self._add_bid(
                    supplier_name=bid_document.name,
                    document=bid_document.document,
                    is_bargaining=False,
                )
            except Exception as e:
                raise e

            # 记录哪些供应商有二次议价
            if bid_document.has_bargaining:
                try:
                    self._add_bid(
                        supplier_name=bid_document.name,
                        document=bid_document.bargaining_document,
                        is_bargaining=True,
                    )
                except Exception as e:
                    raise e

    def _add_bid(self, supplier_name: str, document: Path, is_bargaining: bool = False):
        wb = load_workbook(document)
        sheet_names = [name for name in wb.sheetnames if name in AVAILABLE_SHEET_NAMES]
        for sheet_name in sheet_names:
            print(f"  Adding bid for sheet: {sheet_name}")
            sheet = wb[sheet_name]
            unmerge_and_fill_cells(sheet)
            # try - except can be added here for robustness
            try:
                has_error_header = False
                idx_header = sheet.cell(row=1, column=1).value
                if idx_header not in ["序号"]:
                    has_error_header = True
                name_header = sheet.cell(row=1, column=2).value
                if name_header not in ["产品名称", "名称"]:
                    has_error_header = True
                spec_header = sheet.cell(row=1, column=3).value
                if spec_header not in ["规格", "规格型号"]:
                    has_error_header = True
                unit_header = sheet.cell(row=1, column=4).value
                if unit_header not in ["单位"]:
                    has_error_header = True

                has_price = False
                for col_idx in range(1, sheet.max_column):
                    val_str = str(sheet.cell(row=2, column=col_idx).value)
                    if val_str in ["单价", "含税单价"]:
                        has_price = True
                        break
                if not has_price:
                    has_error_header = True

                if has_error_header:
                    raise Exception()

            except Exception:
                raise Exception(
                    f"{supplier_name}的{'二次' if is_bargaining else ''}报价文件格式有误，请检查。错误工作表 {sheet_name} 。"
                )
            bid_table = import_products_from_bid(
                sheet=sheet, supplier=supplier_name, is_bargaining=is_bargaining
            )

            for summary_table in self.summary_tables:
                if summary_table.table_name == bid_table.table_name:
                    add_supplier(summary_table, bid_table)

                    if supplier_name not in summary_table.suppliers:
                        summary_table.suppliers.append(supplier_name)

                    if (
                        is_bargaining
                        and supplier_name not in summary_table.suppliers_with_bargaining
                    ):
                        summary_table.suppliers_with_bargaining.append(supplier_name)

                    break
        wb.close()

    def save(self):
        for table in self.summary_tables:
            print(
                f"Summary Table: {table.table_name}, Products: {len(table.products)}, Suppliers: {len(table.suppliers)}"
            )
        exporter = Exporter(self.summary_tables)
        exporter.export(str(self.summary_document))
